package com.swotxu.screwweb.util;

import org.apache.commons.lang.StringUtils;
import org.apache.tomcat.util.http.fileupload.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLConnection;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.Map;

/**
 * @Date: 2021/7/12 16:29
 * @Author: xu.hai
 */
public abstract class IOUtil {

    private static final Logger LOGGER = LoggerFactory.getLogger(IOUtil.class);
    public static final boolean FILE_VIEW_ONLINE = true;
    public static final boolean FILE_DOWN_LOAD = false;

    private static final Map<String, String> CONTENT_TYPE_MAP;

    static {
        CONTENT_TYPE_MAP = new HashMap<>();
        CONTENT_TYPE_MAP.put(".doc", "application/msword");
        CONTENT_TYPE_MAP.put(".docx", "application/msword");
        CONTENT_TYPE_MAP.put(".xls", "application/vnd.ms-excel");
        CONTENT_TYPE_MAP.put(".xlsx", "application/vnd.ms-excel");
    }

    /**
     * 根据文件名后缀获取 ContentType
     * @param fileName 文件名（含后缀） test.doc
     * @return  ContentType
     */
    public static String getContentType(String fileName) {
        String contentType = URLConnection.guessContentTypeFromName(fileName);

        if (StringUtils.isBlank(contentType) && StringUtils.contains(fileName, ".")) {
            String suff = fileName.substring(fileName.lastIndexOf(".")).toLowerCase();
            contentType = CONTENT_TYPE_MAP.get(suff);
        }
        if (StringUtils.isBlank(contentType)) {
            contentType = "application/x-download";
        }
        LOGGER.debug("from fileName: {}, to ContentType: {}", fileName, contentType);
        return contentType;
    }

    /**
     * 文件下载、预览
     * @param response  响应消息
     * @param fileName  文件名（含后缀）
     * @param process   文件处理（如文件写入操作）
     * @param isView   是否预览（true-在线预览 false-下载）
     */
    public static void downloadCostom(HttpServletResponse response, String fileName, boolean isView, IOProcess process) {
        try (ServletOutputStream out = response.getOutputStream()) {
            response.setCharacterEncoding(StandardCharsets.UTF_8.name());
            response.setContentType(getContentType(fileName) + ";charset=UTF-8");
            if (!isView) {
                response.setHeader("content-disposition"
                        , "attachment;fileName=" + URLEncoder.encode(fileName, "UTF-8"));
            }
            process.execute(out);
            out.flush();
        } catch (UnsupportedEncodingException e) {
            LOGGER.error("文件名编码异常", e);
        } catch (IOException e) {
            LOGGER.error("文件IO异常", e);
        }
    }

    /**
     * 从文件路径下载预览文件
     * @param response  响应消息
     * @param filePath  文件绝对路径
     * @param isView    是否预览（true-在线预览 false-下载）
     */
    public static void downloadByPath(HttpServletResponse response, String filePath, boolean isView) {
        downloadByPath(response, new File(filePath), isView);
    }
    public static void downloadByPath(HttpServletResponse response, File file, boolean isView) {
        downloadCostom(response, file.getName(), isView, out -> {
            try (InputStream in = new FileInputStream(file)) {
                IOUtils.copy(in, out);
            }
        });
    }

    /**
     * 通过responce输出流写出内容到web
     * @param response
     * @param context
     */
    public static void context2OutWeb(HttpServletResponse response, String context){
        try (PrintWriter writer = response.getWriter()) {
            response.setContentType("text/html;charset=GBK");
            writer.println(context);
        } catch (IOException e) {
            LOGGER.error("消息写入异常", e);
        }
    }

    interface IOProcess {
        void execute(OutputStream out) throws IOException;
    }

    public static void main(String[] args) {
        System.out.println(new File("D:\\WorkFiles\\workspace\\test\\screw\\screw-web\\target\\screw-web-0.0.1-SNAPSHOT.jar").getName());
        System.out.println(new File("D:\\WorkFiles\\workspace\\test\\screw\\screw-web\\target\\screw-web-0.0.1-SNAPSHOT.jar").getName());
        String absolutePath = new File("").getAbsolutePath();
        System.out.println(absolutePath);
        File file = new File(absolutePath, "../screw-maven/pom.xml");
        System.out.println(file);
        System.out.println(file.getName());
        System.out.println(file.exists());
        System.out.println(File.separator);
    }
}
